import {internal} from './api';

export function runCommand(gui, str, done) {
    var commands;
    var model = gui.model;

    try {
        commands = internal.parseConsoleCommands(str);
        // don't add info commands to console history
        // (for one thing, they interfere with target resetting)
        commands = internal.runAndRemoveInfoCommands(commands);
    } catch (e) {
        return done(e, {});
    }
    if (commands.length === 0) return done();
    applyParsedCommands(commands, function(err, flags) {
        if (!err) {
            gui.session.consoleCommands(internal.standardizeConsoleCommands(str));
        }
        if (flags) {
            model.updated(flags); // info commands do not return flags
        }
        done(err);
    });


    function getCommandFlags(commands) {
        return commands.reduce(function(memo, cmd) {
            memo[cmd.name] = true;
            return memo;
        }, {});
    }

    function applyParsedCommands(commands, done) {
        var active = model.getActiveLayer(),
            prevArcs = active.dataset.arcs,
            prevTable = active.layer.data,
            prevTableSize = prevTable ? prevTable.size() : 0,
            prevArcCount = prevArcs ? prevArcs.size() : 0;

        internal.runParsedCommands(commands, model, function(err) {
            var flags = getCommandFlags(commands),
                active2 = model.getActiveLayer(),
                postArcs = active2.dataset.arcs,
                postArcCount = postArcs ? postArcs.size() : 0,
                postTable = active2.layer.data,
                postTableSize = postTable ? postTable.size() : 0,
                sameTable = prevTable == postTable && prevTableSize == postTableSize,
                sameArcs = prevArcs == postArcs && postArcCount == prevArcCount;

            // restore default logging options, in case they were changed by the command
            internal.setStateVar('QUIET', false);
            internal.setStateVar('VERBOSE', false);

            // kludge to signal map that filtered arcs need refreshing
            // TODO: find a better solution, outside the console
            if (!sameArcs) {
                flags.arc_count = true;
            }
            if (sameTable) {
                flags.same_table = true;
            }
            if (active.layer != active2.layer) {
                flags.select = true;
            }
            // signal the map to update even if an error has occured, because the
            // commands may have partially succeeded and changes may have occured to
            // the data.
            done(err, flags);
        });




    }
}


